import 'dart:collection';
import 'dart:io';
import 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';

import '../../image/model/ImageItem.dart';

class ImagePreviewModel {
  static const String BACKSLASH = '/';
  final Map<String, ImageItem> taskIdToImages = HashMap(); // taskId，图片对象
  final Map<String, String> urlToTaskIds = HashMap();

  ImagePreviewModel() {
    FlutterDownloader.registerCallback(downloadCallback);
  }

  Future<void> downloadImage(ImageItem item) async {
    if (urlToTaskIds.containsKey(item.url)) {
      return;
    }
    String parentDirectory = p.dirname(item.localPath);
    final tempName = p.basename(item.localPath).replaceAll('.', '_');
    await ensureDirectoryExists(parentDirectory);
    item.tempPath = "$parentDirectory/$tempName";
    if (kDebugMode) {
      print(
          "ImagePreview: downloadImage,  开始下载: ${item.url}，目标: ${item.tempPath}");
    }
    final taskId = await FlutterDownloader.enqueue(
      url: item.url,
      savedDir: parentDirectory,
      fileName: tempName,
      showNotification: false,
      openFileFromNotification: false,
    );
    addTaskId(item, taskId!);
  }

  void addTaskId(ImageItem image, String taskId) {
    taskIdToImages[taskId] = image;
    urlToTaskIds[image.url] = taskId;
  }

  void removeTaskId(String taskId) {
    taskIdToImages.removeWhere((key, value) => key == taskId);
    urlToTaskIds.removeWhere((key, value) => value == taskId);
  }

  Future<void> ensureDirectoryExists(String dir) async {
    try {
      final directory = Directory(dir);
      // 使用 exists() 方法进行异步检查
      if (!await directory.exists()) {
        // 创建目录并忽略已经存在的目录
        await directory.create(recursive: true);
      }
    } catch (e) {
      // 处理异常，例如权限不足、磁盘空间不足等
      if (kDebugMode) {
        print('Failed to create directory $dir: $e');
      }
      rethrow; // 如果需要，可以重新抛出异常
    }
  }

  static void downloadCallback(String id, int status, int progress) {
    IsolateNameServer.lookupPortByName('downloader_send_port')
        ?.send([id, status, progress]);
  }

  bool updateDownloadProgress(
      String id, DownloadTaskStatus status, int progress) {
    if (kDebugMode) {
      print(
          "ImagePreview: _updateDownloadProgress $status,  progress: $progress, id: $id");
    }
    bool update = false;
    if (taskIdToImages.containsKey(id)) {
      switch (status) {
        case DownloadTaskStatus.complete:
          ImageItem image = taskIdToImages[id]!;
          image.state = ImageState.loaded;
          if (!File(image.localPath).existsSync()) {
            File(image.tempPath).renameSync(image.localPath);
          }
          removeTaskId(id);
          update = true;
          break;
        case DownloadTaskStatus.canceled:
        case DownloadTaskStatus.failed:
          taskIdToImages[id]!.state = ImageState.error;
          removeTaskId(id);
          update = true;
          break;
        default:
          taskIdToImages[id]!.state = ImageState.downloading;
      }
    }
    return update;
  }

  Future<bool> isDownloaded(ImageItem item, String bookId) async {
    if (item.localPath.isEmpty) {
      item.localPath = await getDownloadPath(bookId, item.url);
    }
    File file = File(item.localPath);
    if (file.existsSync()) {
      item.state = ImageState.loaded;
      return true;
    }
    return false;
  }

  Future<String> getDownloadPath(String bookId, String url) async {
    final appFilesDir = await getExternalStorageDirectory();
    // String epubImageDir = getEpubImageDir(bookId, url);
    String name = extractEpubImageName(url);
    String filePath = "${appFilesDir?.path}/KmxsReader/books/$name";
    if (kDebugMode) {
      print("ImagePreview: getDownloadPath,  file: $filePath");
    }
    return filePath;
  }

  String getEpubImageDir(String bookId, String url) {
    try {
      Uri uri = Uri.parse(url);
      // 获取路径部分
      String path = uri.path;
      int startIndex = path.indexOf(BACKSLASH + bookId);
      // 截取从书籍ID开始的后半部分路径
      String temp = path.substring(startIndex + 1);
      temp = temp.substring(bookId.length);
      temp = temp.substring(0, temp.lastIndexOf(BACKSLASH) + 1);
      return temp;
    } catch (e) {
      // 处理异常
      if (kDebugMode) {
        print('Error parsing URL: $e');
      }
    }
    return "";
  }

  String extractEpubImageName(String url) {
    try {
      // 创建 URI 对象
      Uri uri = Uri.parse(url);
      // 获取路径部分
      String path = uri.path;
      // 从路径中提取文件名
      return path.substring(path.lastIndexOf('/') + 1);
    } catch (e) {
      // 处理异常
      return '${url.hashCode}.jpg';
    }
  }

  Future<String> getDownloadTempPath(String filePath) async {
    List<String> paths = filePath.split('/');
    final tempName = paths.last.replaceAll('.', '_');
    return '${paths.first}/$tempName';
  }

  Future<void> cancelTask(ImageItem item) async {
    if (urlToTaskIds.containsKey(item.url)) {
      String taskId = urlToTaskIds[item.url]!;
      await FlutterDownloader.cancel(taskId: taskId);
      removeTaskId(taskId);
    }
  }
}
